home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / decomp / ageval.c next >
Encoding:
C/C++ Source or Header  |  1985-12-18  |  3.7 KB  |  176 lines

  1. # include    <ingres.h>
  2. # include    <tree.h>
  3. # include    <symbol.h>
  4. # include    <pv.h>
  5. # include    "globs.h"
  6. # include    <sccs.h>
  7. # include    <errors.h>
  8.  
  9. SCCSID(@(#)ageval.c    8.3    12/18/85)
  10.  
  11. /*
  12. **    AGEVAL -- evaluate simple aggregate.
  13. **
  14. **    Ageval is passed the tree of a simple aggregate,
  15. **    and an array of space to store the results. The
  16. **    amount of space actually allocated is stored in
  17. **    (*result)->sym.len
  18. **
  19. **    If the aggregate is unique (eg. countu, sumu, avgu)
  20. **    or if the aggregate is multi-variable, special
  21. **    processing is done. A temporary relation is formed
  22. **    with a result domain for each single agg in the tree.
  23. **    Decomp is called to retrieve
  24. **    the values to be aggregated into that relation.
  25. **
  26. **    If the aggregate is unique, then duplicates are
  27. **    removed from the temporary relation.
  28. **
  29. **    Next the aggregate is run on either the original relation
  30. **    or on the temporary relation.
  31. **
  32. **    Finally the result is read from OVQP and if a
  33. **    temporary relation was used, it is destroyed.
  34. **
  35. **    Trace Flags:
  36. **        41
  37. */
  38.  
  39.  
  40. QTREE *
  41. ageval(tree, result)
  42. QTREE    *tree;        /* root of aggregate */
  43. QTREE    *result[];    /* space for results */
  44. {
  45.     register QTREE    *aghead, *resdom, *aop;
  46.     QTREE        *newtree;
  47.     QTREE        *lnodv[MAXDOM + 2];
  48.     int        agbuf[1+AGBUFSIZ/sizeof(int)];
  49.     int        temp_relnum, i;
  50.     extern int    derror();
  51.     extern QTREE    *makroot(), *makavar(), *makresdom();
  52.  
  53. #    ifdef xDTR1
  54.     if (tTf(41, 2))
  55.     {
  56.         printf("entered ageval\n");
  57.         treepr(tree);
  58.     }
  59. #    endif
  60.  
  61.     aghead = tree;
  62.     aop = aghead->left;
  63.     temp_relnum = NORESULT;
  64.  
  65.     /* if PRIME or multi-var, form aggregate domain in temp relation */
  66.     if (prime(aop) || aghead->sym.value.sym_root.tvarc > 1)
  67.     {
  68.         initbuf((char *)agbuf, AGBUFSIZ, AGBUFFULL, derror);
  69.  
  70.         lnodv[lnode(aop, lnodv, 0)] = 0;
  71.  
  72.         /* create new tree for retrieve and give it the qualification */
  73.         newtree = makroot((char *)agbuf);
  74.         newtree->right = aghead->right;
  75.         aghead->right = De.de_qle;
  76.  
  77.         /* put a resdom on new tree for each aop in orig tree */
  78.         /* make each aop in orig tree reference new relation */
  79.         for (i = 0; aop = lnodv[i]; )
  80.         {
  81.  
  82.             /* create resdom for new tree */
  83.             resdom = makresdom((char *)agbuf, aop);
  84.             resdom->sym.value.sym_resdom.resno = ++i;
  85.             resdom->right = aop->right;
  86.  
  87.             /* connect it to newtree */
  88.             resdom->left = newtree->left;
  89.             newtree->left = resdom;
  90.  
  91.             /* make orig aop reference new relation */
  92.             aop->right = makavar(resdom, FREEVAR, i);
  93.         }
  94.  
  95.         /* make result relation */
  96.         temp_relnum = mak_t_rel(newtree, "a", -1);
  97.  
  98.         /* prepare for query */
  99.         mapvar(newtree, 0);
  100.         decomp(newtree, mdRETR, temp_relnum);
  101.         De.de_rangev[FREEVAR].relnum = temp_relnum;
  102.         De.de_sourcevar = FREEVAR;
  103.  
  104.         /* if prime, remove dups */
  105.         if (prime(aghead->left))
  106.         {
  107.             /* modify to heapsort */
  108.             removedups(FREEVAR);
  109.         }
  110.  
  111.     }
  112.  
  113.     De.de_newq = 1;
  114.     De.de_newr = TRUE;
  115.  
  116.     call_ovqp(aghead, mdRETR, NORESULT);    /* call ovqp with no result relation */
  117.     De.de_newq = 0;
  118.  
  119.     /* pick up results */
  120.     readagg_result(result);
  121.  
  122.     /* if temp relation was created, destroy it */
  123.     if (temp_relnum != NORESULT)
  124.         dstr_rel(temp_relnum);
  125.  
  126. }
  127. /*
  128. **    Determine if an aggregate contains any
  129. **    prime aggregates. Note that there might
  130. **    be more than one aggregate.
  131. */
  132.  
  133. prime(aop)
  134. QTREE    *aop;
  135. {
  136.     register QTREE    *a;
  137.  
  138.     a = aop;
  139.     do
  140.     {
  141.         switch (a->sym.value.sym_op.opno)
  142.         {
  143.           case opCOUNTU:
  144.           case opSUMU:
  145.           case opAVGU:
  146.             return (TRUE);
  147.         }
  148.     } while (a = a->left);
  149.     return (FALSE);
  150. }
  151. /*
  152. **    Remove dups from an unopened relation
  153. **    by calling heapsort
  154. */
  155.  
  156. removedups(var)
  157. int    var;
  158. {
  159.     register char    *p;
  160.     char        *rangename();
  161.  
  162.     closer1(var);    /* guarantee that relation has been closed */
  163.     initp();
  164.     p = rangename(var);    /* get name of relation */
  165. #    ifdef xDTR1
  166.     if (tTf(41, 1))
  167.     {
  168.         printf("removing dups from %s\n", p);
  169.     }
  170. #    endif
  171.     setp(PV_STR, p);
  172.     setp(PV_STR,"heapsort");
  173.     setp(PV_STR,"num");
  174.     call_dbu(mdMODIFY, FALSE);
  175. }
  176.